package org.asteriskjava.manager.event;

/**
 * AgiExecEvents are triggered when an AGI command is executed. For each command two events are triggered:
 * one before excution ("Start") and one after execution ("End").
 * <br>
 * The following sub events are reported:
 * <ul>
 * <li>Start: Execution of an AGI command has started.</li>
 * <li>End:   Execution of an AGI command has finished.</li>
 * </ul>
 * It is implemented in <code>res/res_agi.c</code>.
 * <br>
 * Available since Asterisk 1.6
 *
 * @author srt
 * @version $Id$
 * @since 1.0.0
 */
public class AgiExecEvent extends ManagerEvent
{
	/**
	 * Serializable version identifier.
	 */
	static final long serialVersionUID = 0L;

	/**
	 * Execution of an AGI command has started.
	 */
	public static final String SUB_EVENT_START = "Start";

	/**
	 * Execution of an AGI command has finished.
	 */
	public static final String SUB_EVENT_END = "End";

	private String channel;
	private String subEvent;
	private String commandId;
	private String command;
	private Integer resultCode;
	private String result;
	private String accountCode;

	public String getUniqueId()
	{
		return uniqueId;
	}

	public void setUniqueId(String uniqueId)
	{
		this.uniqueId = uniqueId;
	}

	private String uniqueId;

	/**
	 * Creates a new AgiExecEvent.
	 *
	 * @param source
	 */
	public AgiExecEvent(Object source)
	{
		super(source);
	}

	/**
	 * Returns the name of the channel this event occurred on.
	 *
	 * @return the name of the channel this event occurred on.
	 */
	public String getChannel()
	{
		return channel;
	}

	/**
	 * Sets the name of the channel this event occurred on.
	 *
	 * @param channel the name of the channel this event occurred on.
	 */
	public void setChannel(String channel)
	{
		this.channel = channel;
	}

	/**
	 * Returns the sub event type. This is either "Start" or "End".
	 *
	 * @return the sub event type.
	 * @see #SUB_EVENT_START
	 * @see #SUB_EVENT_END
	 */
	public String getSubEvent()
	{
		return subEvent;
	}

	/**
	 * Sets the sub event type.
	 *
	 * @param subEvent the sub event type.
	 */
	public void setSubEvent(String subEvent)
	{
		this.subEvent = subEvent;
	}

	/**
	 * Returns the command id. The command is a random number generated by Asterisk that allows matching the "End" sub event with the corresponding "Start" sub event.
	 *
	 * @return the command id.
	 */
	public String getCommandId()
	{
		return commandId;
	}

	/**
	 * Sets the command id.
	 *
	 * @param commandId the command id.
	 */
	public void setCommandId(String commandId)
	{
		this.commandId = commandId;
	}

	/**
	 * Returns the AGI command.
	 *
	 * @return the AGI command.
	 */
	public String getCommand()
	{
		return command;
	}

	/**
	 * Sets the AGI command.
	 *
	 * @param command the AGI command.
	 */
	public void setCommand(String command)
	{
		this.command = command;
	}

	/**
	 * Returns the result code.
	 *
	 * @return the result code.
	 */
	public Integer getResultCode()
	{
		return resultCode;
	}

	/**
	 * Sets the result code.
	 *
	 * @param resultCode the result code.
	 */
	public void setResultCode(Integer resultCode)
	{
		this.resultCode = resultCode;
	}

	/**
	 * Returns the result as a string.<p>
	 * They correspond to the numeric values returned by {@link #getResultCode()}. Usually you will want to stick with the numeric values.<p>
	 * Possible values are:
	 * <ul>
	 * <li>Failure (corresponds to result code -1)</li>
	 * <li>Success (corresponds to result code 200)</li>
	 * <li>KeepAlive (corresponds to result code 210)</li>
	 * <li>Command not permitted on a dead channel (corresponds to result code 511)</li>
	 * <li>Usage (corresponds to result code 520)</li>
	 * </ul>
	 *
	 * @return a string respresentation of the result.
	 */
	public String getResult()
	{
		return result;
	}

	/**
	 * Sets the string respresentation of the result.
	 *
	 * @param result a string respresentation of the result.
	 */
	public void setResult(String result)
	{
		this.result = result;
	}

	/**
	 * Returns the account code set for CDR.
	 *
	 * @return string
	 */
	public String getAccountCode()
	{
		return accountCode;
	}

	/**
	 * Sets the account code used for billing in the CDR.
	 * <br>
	 * This will be the filename asterisk stores the billing informations in, so it should only use lowercase letters, numbers, hyphen and underscore.
	 *
	 * @param accountCode
	 */
	public void setAccountCode(String accountCode)
	{
		this.accountCode = accountCode;
	}

	/**
	 * Checks is this a start sub event.
	 *
	 * @return <code>true</code> if this is a "Start" sub event, <code>false</code> otherwise.
	 */
	public boolean isStart()
	{
		return isSubEvent(SUB_EVENT_START);
	}

	/**
	 * Checks is this an end sub event.
	 *
	 * @return <code>true</code> if this is an "End" sub event, <code>false</code> otherwise.
	 */
	public boolean isEnd()
	{
		return isSubEvent(SUB_EVENT_END);
	}

	private boolean isSubEvent(String subEvent)
	{
		return this.subEvent != null && this.subEvent.equalsIgnoreCase(subEvent);
	}
}
